<template>
  <div class="matching-detail-container">
    <div class="page-header">
      <div class="page-title">匹配详情</div>
      <div class="page-actions">
        <el-button icon="Back" @click="$router.back()">返回</el-button>
        <el-button icon="Printer" @click="handlePrintReport">导出报告</el-button>
      </div>
    </div>

    <!-- 漏洞与资产信息 -->
    <div class="detail-section">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card class="detail-card">
            <template #header>
              <div class="card-header">
                <span>漏洞信息</span>
                <el-tag :type="getTagType(vulnerabilityInfo.level)" class="level-tag">
                  {{ formatLevel(vulnerabilityInfo.level) }}
                </el-tag>
              </div>
            </template>
            <el-descriptions :column="1" border>
              <el-descriptions-item label="漏洞ID">
                <el-link type="primary" @click="handleViewVulnDetail">{{ vulnerabilityInfo.id }}</el-link>
              </el-descriptions-item>
              <el-descriptions-item label="漏洞名称">{{ vulnerabilityInfo.name }}</el-descriptions-item>
              <el-descriptions-item label="漏洞类型">{{ vulnerabilityInfo.type }}</el-descriptions-item>
              <el-descriptions-item label="CVE编号">
                <el-link type="info" :href="`https://cve.mitre.org/cgi-bin/cvename.cgi?name=${vulnerabilityInfo.cveId}`" target="_blank">
                  {{ vulnerabilityInfo.cveId }}
                </el-link>
              </el-descriptions-item>
              <el-descriptions-item label="发布日期">{{ vulnerabilityInfo.publishDate }}</el-descriptions-item>
              <el-descriptions-item label="影响版本">{{ vulnerabilityInfo.affectedVersion }}</el-descriptions-item>
              <el-descriptions-item label="修复版本">{{ vulnerabilityInfo.fixedVersion }}</el-descriptions-item>
            </el-descriptions>
          </el-card>
        </el-col>
        
        <el-col :span="12">
          <el-card class="detail-card">
            <template #header>
              <div class="card-header">
                <span>资产信息</span>
                <el-tag type="success" class="asset-tag">已匹配</el-tag>
              </div>
            </template>
            <el-descriptions :column="1" border>
              <el-descriptions-item label="资产名称">{{ assetInfo.name }}</el-descriptions-item>
              <el-descriptions-item label="IP地址">{{ assetInfo.ip }}</el-descriptions-item>
              <el-descriptions-item label="域名">{{ assetInfo.domain }}</el-descriptions-item>
              <el-descriptions-item label="所属部门">{{ assetInfo.department }}</el-descriptions-item>
              <el-descriptions-item label="操作系统">{{ assetInfo.os }}</el-descriptions-item>
              <el-descriptions-item label="开放服务">{{ assetInfo.services }}</el-descriptions-item>
              <el-descriptions-item label="最近扫描">{{ assetInfo.lastScan }}</el-descriptions-item>
            </el-descriptions>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 匹配信息 -->
    <el-card class="matching-info-card">
      <template #header>
        <div class="card-header">匹配信息</div>
      </template>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="匹配方式">{{ matchingInfo.type }}</el-descriptions-item>
        <el-descriptions-item label="匹配时间">{{ matchingInfo.time }}</el-descriptions-item>
        <el-descriptions-item label="匹配依据">{{ matchingInfo.basis }}</el-descriptions-item>
        <el-descriptions-item label="匹配分值">
          <el-progress :percentage="matchingInfo.score" :color="getProgressColor" />
        </el-descriptions-item>
        <el-descriptions-item label="匹配备注" :span="2">{{ matchingInfo.notes }}</el-descriptions-item>
      </el-descriptions>
    </el-card>

    <!-- 漏洞详情 -->
    <el-card class="vuln-detail-card">
      <template #header>
        <div class="card-header">漏洞详情</div>
      </template>
      <el-tabs v-model="activeTab">
        <el-tab-pane label="漏洞描述" name="description">
          <div class="markdown-content" v-html="renderedDescription"></div>
        </el-tab-pane>
        <el-tab-pane label="影响范围" name="impact">
          <div class="markdown-content" v-html="renderedImpact"></div>
        </el-tab-pane>
        <el-tab-pane label="修复建议" name="solution">
          <div class="markdown-content" v-html="renderedSolution"></div>
        </el-tab-pane>
        <el-tab-pane label="参考链接" name="references">
          <div class="references-list">
            <el-space direction="vertical" alignment="flex-start" :size="15">
              <div v-for="(link, index) in vulnerabilityInfo.references" :key="index" class="reference-item">
                <el-link :href="link.url" target="_blank" type="primary">{{ link.title }}</el-link>
                <span class="reference-source">{{ link.source }}</span>
              </div>
            </el-space>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <!-- 验证信息 -->
    <el-card class="verification-card">
      <template #header>
        <div class="card-header">
          <span>验证信息</span>
          <div>
            <el-tag :type="getVerificationTagType(verificationInfo.status)">
              {{ formatVerificationStatus(verificationInfo.status) }}
            </el-tag>
            <el-button 
              v-if="verificationInfo.status !== 'verified'" 
              type="primary" 
              size="small" 
              style="margin-left: 10px"
              @click="handleStartVerification">
              开始验证
            </el-button>
          </div>
        </div>
      </template>
      
      <div v-if="verificationInfo.status === 'verified'">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="验证人员">{{ verificationInfo.verifier }}</el-descriptions-item>
          <el-descriptions-item label="验证时间">{{ verificationInfo.time }}</el-descriptions-item>
          <el-descriptions-item label="验证方法">{{ verificationInfo.method }}</el-descriptions-item>
          <el-descriptions-item label="验证结果">
            <el-tag type="success" v-if="verificationInfo.result === 'success'">成功</el-tag>
            <el-tag type="danger" v-else>失败</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="验证说明" :span="2">{{ verificationInfo.description }}</el-descriptions-item>
        </el-descriptions>
        
        <!-- 验证证据 -->
        <div v-if="verificationInfo.evidence.length" class="evidence-section">
          <div class="evidence-title">验证证据</div>
          <div class="evidence-gallery">
            <div v-for="(item, index) in verificationInfo.evidence" :key="index" class="evidence-item">
              <el-image 
                :src="item.url" 
                :preview-src-list="verificationInfo.evidence.map(img => img.url)"
                fit="cover">
              </el-image>
              <div class="evidence-caption">{{ item.caption }}</div>
            </div>
          </div>
        </div>
      </div>
      
      <el-empty v-else description="暂无验证信息">
        <template #image>
          <el-icon class="empty-icon"><Warning /></el-icon>
        </template>
      </el-empty>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Warning } from '@element-plus/icons-vue'
import { useRoute, useRouter } from 'vue-router'

// 路由
const route = useRoute()
const router = useRouter()

// 活动标签
const activeTab = ref('description')

// 模拟漏洞信息
const vulnerabilityInfo = reactive({
  id: 'VLN-2023042',
  name: 'Apache Struts2 远程命令执行漏洞',
  type: '远程命令执行',
  level: 'critical',
  cveId: 'CVE-2023-32032',
  publishDate: '2023-05-15',
  affectedVersion: 'Struts 2.0.0 - 2.5.28',
  fixedVersion: 'Struts 2.5.30',
  description: `
## 漏洞概述

这是一个影响Apache Struts2框架的远程命令执行漏洞，攻击者可以通过构造特殊的HTTP请求执行任意命令。该漏洞的CVSS评分为9.8（严重），因为它允许未经身份验证的远程攻击者在受影响的系统上执行任意代码。

## 漏洞原理

漏洞存在于Struts2的OGNL表达式处理机制中，当接收用户输入并在未经适当验证的情况下将其传递给OGNL解析器时，攻击者可以注入恶意OGNL表达式，从而绕过安全限制并在目标服务器上执行任意代码。
  `,
  impact: `
## 影响范围

该漏洞影响运行Apache Struts2 2.0.0至2.5.28版本的所有Web应用程序。攻击者可以：

1. 执行远程命令，获取服务器控制权
2. 访问敏感数据
3. 破坏系统完整性
4. 在受影响的服务器上部署后门

## 受影响的组件

- Apache Struts2核心组件
- 使用受影响版本Struts2的Web应用程序
  `,
  solution: `
## 修复建议

### 立即更新

将Apache Struts2升级到最新的2.5.30版本或更高版本，该版本已修复此漏洞。

### 临时缓解措施

如果无法立即更新，请考虑以下缓解措施：

1. 实施Web应用程序防火墙(WAF)规则以阻止包含恶意OGNL表达式的请求
2. 限制对Struts2应用程序的外部访问
3. 监控系统异常行为

### 配置更改

在\`struts.xml\`中添加以下配置：

\`\`\`xml
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.ognl.allowStaticMethodAccess" value="false" />
\`\`\`
  `,
  references: [
    { 
      title: 'Apache Struts Security Bulletin', 
      url: 'https://struts.apache.org/security.html', 
      source: 'Apache'
    },
    { 
      title: 'CVE-2023-32032 Details', 
      url: 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32032', 
      source: 'MITRE'
    },
    { 
      title: '详细漏洞分析报告', 
      url: 'https://example.com/vuln-report', 
      source: '安全团队分析'
    }
  ]
})

// 模拟资产信息
const assetInfo = reactive({
  name: '内部Web服务器',
  ip: '192.168.1.100',
  domain: 'web.example.com',
  department: '研发部',
  os: 'CentOS 7.9',
  services: 'HTTP(80), HTTPS(443), SSH(22)',
  lastScan: '2023-10-15 14:30:25'
})

// 模拟匹配信息
const matchingInfo = reactive({
  type: '自动匹配',
  time: '2023-10-16 09:45:32',
  basis: '基于资产指纹识别，发现该服务器运行Apache Struts 2.5.26版本',
  score: 85,
  notes: '通过资产自动扫描时发现的匹配，基于Web应用指纹识别结果，匹配度较高。建议进行验证确认。'
})

// 模拟验证信息
const verificationInfo = reactive({
  status: 'verified', // pending, in_progress, verified
  verifier: '张安全',
  time: '2023-10-17 15:23:45',
  method: 'POC验证',
  result: 'success',
  description: '使用专用POC工具成功验证漏洞存在。构造特定的HTTP请求后，成功在目标服务器上执行了测试命令，确认漏洞可被利用。',
  evidence: [
    {
      url: 'https://via.placeholder.com/400x200?text=验证截图1',
      caption: 'POC测试请求截图'
    },
    {
      url: 'https://via.placeholder.com/400x200?text=验证截图2',
      caption: '命令执行结果截图'
    }
  ]
})

// 格式化危害等级
const formatLevel = (level) => {
  const levelMap = {
    'critical': '严重',
    'high': '高危',
    'medium': '中危',
    'low': '低危'
  }
  return levelMap[level] || level
}

// 获取标签类型
const getTagType = (level) => {
  const typeMap = {
    'critical': 'danger',
    'high': 'warning',
    'medium': '',
    'low': 'info'
  }
  return typeMap[level] || ''
}

// 获取验证状态标签类型
const getVerificationTagType = (status) => {
  const typeMap = {
    'pending': 'info',
    'in_progress': 'warning',
    'verified': 'success'
  }
  return typeMap[status] || ''
}

// 格式化验证状态
const formatVerificationStatus = (status) => {
  const statusMap = {
    'pending': '待验证',
    'in_progress': '验证中',
    'verified': '已验证'
  }
  return statusMap[status] || status
}

// 获取进度条颜色
const getProgressColor = computed(() => {
  if (matchingInfo.score >= 80) return '#67C23A'
  if (matchingInfo.score >= 50) return '#E6A23C'
  return '#F56C6C'
})

// 渲染Markdown内容（简单模拟，实际项目中应使用markdown-it等库）
const renderedDescription = computed(() => {
  return vulnerabilityInfo.description
    .replace(/## (.*?)\n/g, '<h2>$1</h2>\n')
    .replace(/\n/g, '<br>')
})

const renderedImpact = computed(() => {
  return vulnerabilityInfo.impact
    .replace(/## (.*?)\n/g, '<h2>$1</h2>\n')
    .replace(/\n\n/g, '<br><br>')
    .replace(/\n([0-9]+\.)/g, '<br>$1')
})

const renderedSolution = computed(() => {
  return vulnerabilityInfo.solution
    .replace(/## (.*?)\n/g, '<h2>$1</h2>\n')
    .replace(/### (.*?)\n/g, '<h3>$1</h3>\n')
    .replace(/\n\n/g, '<br><br>')
    .replace(/\n([0-9]+\.)/g, '<br>$1')
    .replace(/```(.*?)```/gs, '<pre class="code-block">$1</pre>')
})

// 查看漏洞详情
const handleViewVulnDetail = () => {
  console.log('查看漏洞详情')
  ElMessage.info('正在跳转到漏洞详情页面')
}

// 导出报告
const handlePrintReport = () => {
  console.log('导出报告')
  ElMessage.success('报告生成成功，正在下载')
}

// 开始验证
const handleStartVerification = () => {
  ElMessage.success('已将该漏洞加入验证队列，稍后将开始验证')
  verificationInfo.status = 'in_progress'
}

// 初始化
onMounted(() => {
  // 从路由参数中获取匹配ID
  const matchId = route.params.id
  console.log('加载匹配ID:', matchId)
  
  // 这里可以根据ID请求匹配详情数据
})
</script>

<style lang="scss" scoped>
.matching-detail-container {
  padding: 20px;
  
  .page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    
    .page-title {
      font-size: 20px;
      font-weight: bold;
      color: var(--text-color);
    }
    
    .page-actions {
      display: flex;
      gap: 10px;
    }
  }
  
  .detail-section {
    margin-bottom: 20px;
  }
  
  .detail-card {
    height: 100%;
    
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-weight: bold;
      
      .level-tag, .asset-tag {
        margin-left: 10px;
      }
    }
  }
  
  .matching-info-card,
  .vuln-detail-card,
  .verification-card {
    margin-bottom: 20px;
    
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-weight: bold;
    }
  }
  
  .markdown-content {
    padding: 10px;
    
    h2 {
      font-size: 18px;
      font-weight: bold;
      margin-top: 15px;
      margin-bottom: 10px;
      color: var(--text-color);
    }
    
    h3 {
      font-size: 16px;
      font-weight: bold;
      margin-top: 12px;
      margin-bottom: 8px;
      color: var(--text-color);
    }
    
    .code-block {
      background-color: var(--code-bg);
      padding: 10px;
      border-radius: 4px;
      font-family: monospace;
      overflow-x: auto;
      margin: 10px 0;
    }
  }
  
  .references-list {
    padding: 10px;
    
    .reference-item {
      display: flex;
      align-items: center;
      
      .reference-source {
        margin-left: 10px;
        color: var(--text-color-secondary);
        font-size: 13px;
      }
    }
  }
  
  .evidence-section {
    margin-top: 20px;
    
    .evidence-title {
      font-weight: bold;
      margin-bottom: 15px;
      color: var(--text-color);
    }
    
    .evidence-gallery {
      display: flex;
      flex-wrap: wrap;
      gap: 15px;
      
      .evidence-item {
        width: 400px;
        
        .el-image {
          width: 100%;
          height: 200px;
          border-radius: 4px;
          overflow: hidden;
          box-shadow: var(--box-shadow-light);
        }
        
        .evidence-caption {
          margin-top: 5px;
          font-size: 13px;
          color: var(--text-color-secondary);
          text-align: center;
        }
      }
    }
  }
  
  .empty-icon {
    font-size: 60px;
    color: var(--text-color-secondary);
  }
}
</style> 